class AttributeEngine:

    @staticmethod
    def read_attributes(class_reader, constant_pool):
        # 属性表的个数
        count = class_reader.read_u2()
        attrs = []
        for i in range(0, count):
            # 构造某个具体属性 对象
            attr = AttributeEngine.make_attr(constant_pool, class_reader)
            # 解析属性
            attr.read()
            attrs.append(attr)
        return attrs

    @staticmethod
    def make_attr(constant_pool, class_reader):
        name_index = class_reader.read_u2()
        # 先通过下标找到utf8常量，然后获取其值
        attr_name = constant_pool[name_index].val
        # 属性数据的长度
        attr_len = class_reader.read_u4()
        if attr_name == 'Code':
            return CodeAttribute(constant_pool, class_reader)
        elif attr_name == 'ConstantValue':
            return ConstantValueAttribute(constant_pool, class_reader)
        elif attr_name == 'Deprecated':
            return DeprecatedAttribute(constant_pool, class_reader)
        elif attr_name == 'Exceptions':
            return ExceptionsAttribute(constant_pool, class_reader)
        elif attr_name == 'LineNumberTable':
            return LineNumberTableAttribute(constant_pool, class_reader)
        elif attr_name == 'LocalVariableTable':
            return LocalVariableTableAttribute(constant_pool, class_reader)
        elif attr_name == 'SourceFile':
            return SourceFileAttribute(constant_pool, class_reader)
        elif attr_name == 'Synthetic':
            return SyntheticAttribute(constant_pool, class_reader)
        return UnparsedAttribute(attr_name, attr_len, constant_pool, class_reader)


# Code属性 ： 存放字节码等方法相关信息
class CodeAttribute:
    def __init__(self, constant_pool, class_reader):
        # 操作数栈的最大深度
        self.maxStack = None
        # 局部变量表大小
        self.maxLocals = None
        # 方法 字节码
        self.code = []
        # 异常处理表
        self.exceptionTable = []
        # 属性表
        self.attributes = []
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        self.maxStack = self.reader.read_u2()
        self.maxLocals = self.reader.read_u2()
        code_len = self.reader.read_u4()
        self.code = self.reader.read_bytes(code_len)
        ex_table_len = self.reader.read_u2()
        for i in range(0, ex_table_len):
            self.exceptionTable.append(ExceptionTableEntry(self.reader))
        # 读取 属性表
        self.attributes = AttributeEngine.read_attributes(self.reader,
                                                          self.constant_pool)


# 异常处理表
class ExceptionTableEntry:
    def __init__(self, reader):
        self.start_pc = reader.read_u2()
        self.end_pc = reader.read_u2()
        self.handler_pc = reader.read_u2()
        self.catch_type = reader.read_u2()


# ConstantValue属性 : 用于表示常量表达式的值
class ConstantValueAttribute:
    def __init__(self, constant_pool, class_reader):
        # 指向CONSTANT_Utf8_info常量
        self.constantValueIndex = None
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        self.constantValueIndex = self.reader.read_u2()


# Deprecated和Synthetic属性 : 仅起标记作用，不包含任何数据
class DeprecatedAttribute:
    def __init__(self, constant_pool, class_reader):
        pass

    def read(self):
        pass


# Exceptions属性 :  记录方法抛出的异常表
class ExceptionsAttribute:
    def __init__(self, constant_pool, class_reader):
        self.exceptionIndexTable = []
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        self.exceptionIndexTable = self.reader.read_u2s()


# LineNumberTable属性 :  存放方法的行号信息，
class LineNumberTableAttribute:
    def __init__(self, constant_pool, class_reader):
        self.lineNumberTable = []
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        table_len = self.reader.read_u2()
        for i in range(0, table_len):
            self.lineNumberTable.append(LineNumberTableEntry(self.reader))


class LineNumberTableEntry:
    def __init__(self, reader):
        self.startPc = reader.read_u2()
        self.lineNumber = reader.read_u2()


# LocalVariableTable属性表中存放方法的局部变量信息
class LocalVariableTableAttribute:
    def __init__(self, constant_pool, class_reader):
        self.localVariableTable = []
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        table_len = self.reader.read_u2()
        for i in range(0, table_len):
            self.localVariableTable.append(LocalVariableTableEntry(self.reader))


class LocalVariableTableEntry:
    def __init__(self, reader):
        self.startPc = reader.read_u2()
        self.length = reader.read_u2()
        self.nameIndex = reader.read_u2()
        self.descriptorIndex = reader.read_u2()
        self.index = reader.read_u2()


# SourceFile属性 : 用于指出源文件名
class SourceFileAttribute:
    def __init__(self, constant_pool, class_reader):
        self.sourceFileIndex = None
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader

    def read(self):
        self.sourceFileIndex = self.reader.read_u2()


# Deprecated和Synthetic属性 : 仅起标记作用，不包含任何数据
class SyntheticAttribute:
    def __init__(self, constant_pool, class_reader):
        pass

    def read(self):
        pass


# 未实现的属性
class UnparsedAttribute:
    def __init__(self, attr_name, attr_len, constant_pool, class_reader):
        # 常量池
        self.constant_pool = constant_pool
        self.reader = class_reader
        self.attr_name = attr_name
        self.attr_len = attr_len
        self.info = None

    def read(self):
        self.info = self.reader.read_bytes(self.attr_len)
